This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
Chunk is for running the code
# ctrl+alt+I
# CRAN version
if (!require('leaflet')) install.packages('leaflet')
# Or Github version
if (!require('devtools')) install.packages('devtools')
devtools::install_github('rstudio/leaflet')
## glue (1.7.0 -> 1.8.0) [CRAN]
##
## There is a binary version available but the source version is later:
## binary source needs_compilation
## glue 1.7.0 1.8.0 TRUE
##
## Binaries will be installed
## package 'glue' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\yanawu\AppData\Local\Temp\Rtmp4YNTLc\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
## checking for file 'C:\Users\yanawu\AppData\Local\Temp\Rtmp4YNTLc\remotes1081847e76145\rstudio-leaflet-9bf137b/DESCRIPTION' ... checking for file 'C:\Users\yanawu\AppData\Local\Temp\Rtmp4YNTLc\remotes1081847e76145\rstudio-leaflet-9bf137b/DESCRIPTION' ... ✔ checking for file 'C:\Users\yanawu\AppData\Local\Temp\Rtmp4YNTLc\remotes1081847e76145\rstudio-leaflet-9bf137b/DESCRIPTION' (441ms)
## ─ preparing 'leaflet': (1.8s)
## checking DESCRIPTION meta-information ... checking DESCRIPTION meta-information ... ✔ checking DESCRIPTION meta-information
## ─ checking for LF line-endings in source and make files and shell scripts (904ms)
## ─ checking for empty or unneeded directories
## Removed empty directory Removed empty directory 'leaflet/vignettes'
## ─ building 'leaflet_2.2.2.9000.tar.gz'
##
##
# Or manually load packages in R
# Packages - Install
library("rstudioapi")
script_path <- normalizePath(dirname(rstudioapi::getActiveDocumentContext()$path))
setwd(script_path)
The function leaflet() is called, followed by different layers with add*(). The pipe operator %>% is used to add layers on top of each other.
Many free third-party basemaps can be added using the addProviderTiles()
See here for the complete list of the third-oarty basemaps
basemap <- leaflet() %>%
addProviderTiles(
"CartoDB.Positron",
group = "CartoDB"
) %>%
addProviderTiles(
"OpenStreetMap",
# give the layer a name
group = "OpenStreetMap"
) %>%
addProviderTiles("OpenTopoMap",group = 'Topology')
basemap
Using setView() to set up the view of map (center and zoom level)
Using the center of Worcester: longitude:-71.81, latitude; 42.27, zoom = 15
zoom_basemap = basemap %>% setView(lng = -71.81, lat = 42.27, zoom = 15)
zoom_basemap
Using addLayersControl to switch layers on and off.
Two important parameters: baseGroups and position
You need to assign a name to each layer using groups and then use the function to define the base groups (layers that can be selected one at a time).
zoom_basemap %>% addLayersControl(baseGroups = c('Topology', "OpenStreetMap","CartoDB"),
position = 'topleft')
You can place a marker on the plot by providing coordinates through the lng (longitude) and lat (latitude) arguments of the addMarkers function. This function accepts either a single value or a vector of values for each argument.
basemap %>%
addMarkers(lat = 42.252,
lng = -71.824,
label = "Clark")
icon.home <- makeAwesomeIcon(
icon = "home", markerColor = "blue",
library = "fa",
iconColor = "white"
)
basemap %>%
addAwesomeMarkers(
lat = 42.252,
lng = -71.824,
label = "Clark",
icon = icon.home
)
Worcester, MA, is home to numerous parks that offer a variety of amenities, enriching the quality of life for its residents. The data below represents a selection of parks in the city and serves as a demonstration for educational purposes. It does not encompass all parks in Worcester.
parks.csv data includes the location for several parks in Worcester city
parks = read.csv('parks.csv')
head(parks)
## park_name x y
## 1 Elm Park -71.8165 42.2674
## 2 Green Hill Park -71.7883 42.2813
## 3 Institute Park -71.8085 42.2743
## 4 East Park -71.7874 42.2635
## 5 Newton Hill -71.8342 42.2712
## 6 Crompton Park -71.8050 42.2482
lng and lat can be a vector, get the x and y from parks
A vector in R is the most basic data structure and is used to store a collection of values of the same type. Vectors can hold numeric, character, logical, or other types of data, but each vector must contain only one data type.
basemap %>% addMarkers(lng = parks$x, lat = parks$y,label = parks$park_name)
icons_list <- icons(iconUrl = 'https://raw.githubusercontent.com/gisynw/ssj-30262/refs/heads/main/docs/Lectures/Week06_R_Mapping/trees.png', iconWidth = 20, iconHeight = 20)
basemap %>% addMarkers(lng = parks$x, lat = parks$y, icon = icons_list, label = parks$park_name)
Add value from from names column in Parks using popup parameter or label parameter to see the difference
basemap %>% addMarkers(lng = parks$x, lat = parks$y, icon = icons_list, popup = parks$park_name )
Data Source: MassGIS Data: MassDEP Water Quality Monitoring Stations
Step 1: Check the projection of the leaflet Map
print(c('projection of basemap: ', basemap$x$options$crs$crsClass))
## [1] "projection of basemap: " "L.CRS.EPSG3857"
Step 2: Do the Transformation
library(sf )
## Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
water_quality = read_sf('./water_quality_station/worcester_station.shp')
print(c("original coordinate system:" , st_crs(water_quality)$epsg))
## [1] "original coordinate system:" "26986"
tf_water <- st_transform(water_quality, crs = '+proj=longlat +datum=WGS84')
print(tf_water$geometry)
## Geometry set for 66 features
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -71.85575 ymin: 42.22497 xmax: -71.74551 ymax: 42.30798
## Geodetic CRS: +proj=longlat +datum=WGS84
## First 5 geometries:
## POINT (-71.83102 42.25056)
## POINT (-71.82584 42.23909)
## POINT (-71.85575 42.23359)
## POINT (-71.78715 42.22497)
## POINT (-71.80314 42.24174)
Step 3: Define a color palette based on the ‘category’ column
unique(tf_water$SURVEYTYPE)
## [1] "Benthic Macroinvertebrate" "Fish Toxics"
## [3] "Water Quality" "Fish Population"
# devtools::install_github("awhstin/awtools")
library('awtools')
palette_pts <- colorFactor(palette = mpalette, domain = tf_water$SURVEYTYPE)
leaflet(data = tf_water) %>%
addTiles() %>% # Add a basemap
addCircleMarkers(
fillColor = ~palette_pts(SURVEYTYPE), # Color based on the 'category' column
fillOpacity = 0.8, # Adjust opacity
radius = 5, # Set marker size
stroke = TRUE, # Add stroke to the markers
weight = 1, # Set stroke weight
color = "#000000",
label = tf_water$SURVEYTYPE
)
leaflet(data = tf_water) %>%
addTiles() %>% # Add a basemap
addCircleMarkers(
fillColor = ~palette_pts(SURVEYTYPE), # Color based on the 'category' column
fillOpacity = 0.8, # Adjust opacity
radius = 5, # Set marker size
stroke = TRUE, # Add stroke to the markers
weight = 1, # Set stroke weight
color = "#000000",
label = tf_water$SURVEYTYPE
) %>%
addLegend(data = tf_water,
position = "bottomright",
pal = palette_pts,
values = ~SURVEYTYPE,
title = "Survey Type",
opacity = 1)
Before adding Polygon, Please transform your map to the leaflet projection
# importing rstudioapi package
library("rstudioapi")
# retrieving path from getSourceEditorContext()
# using $ operator
getSourceEditorContext()$path
## [1] "M:/Github_repo/ssj-30262/docs/Lectures/Week06_R_Mapping/Week06_R_Mapping.Rmd"
getwd()
## [1] "M:/Github_repo/ssj-30262/docs/Lectures/Week06_R_Mapping"
water_pond = read_sf('.\\Lakes_Ponds_Rivers\\Lakes_Ponds_Rivers.shp')
tf_pond <- st_transform(water_pond, crs = '+proj=longlat +datum=WGS84')
leaflet() %>%
addProviderTiles(
"CartoDB.Positron",
group = "OpenTopo"
) %>%
addPolygons(data = tf_pond, color = "blue", label = tf_pond$NAME, fillOpacity = 1)
Data Source: Winter Parking Ban
Step 1: Load data
parking_line = read_sf('.\\winter_ban\\Winter_Parking_Ban.shp')
tf_line <- st_transform(parking_line, crs = '+proj=longlat +datum=WGS84')
Step 2: Check NA value in tf_line$BanType If NA exist in value, then palette will generate error
unique(tf_line$BanType)
## [1] "NON-APPLICABLE"
## [2] "PERMANENT"
## [3] "DECLARED"
## [4] "STATE OWNED - NO WORCESTER WINTER PARKING BAN"
## [5] NA
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
tf_line <- tf_line %>%
mutate(BanType = ifelse(is.na(BanType), 'NON-APPLICABLE', BanType))
unique(tf_line$BanType)
## [1] "NON-APPLICABLE"
## [2] "PERMANENT"
## [3] "DECLARED"
## [4] "STATE OWNED - NO WORCESTER WINTER PARKING BAN"
palette_line <- colorFactor(palette = mpalette, domain = tf_line$BanType)
#
leaflet() %>%
addProviderTiles(
"CartoDB.Positron",
group = "OpenTopo"
) %>%
addPolylines( data = tf_line,
color = ~palette_line(BanType),
weight = 2,
label = ~BanType
) %>%
addLegend(data = tf_line,
position = "bottomright",
pal = palette_line,
values = ~BanType,
title = "BanType",
opacity = 1)
You will need to assign a name to each layer using groups, then use the function to define the base groups (which can be selected one at a time) and the overlay groups (which can be selected independently).
final_map = leaflet() %>%
addProviderTiles(
"CartoDB.Positron",
group = "OpenTopo"
) %>%
addProviderTiles(
"OpenStreetMap.Mapnik",
group = "OpenStreetMap"
) %>%
addPolylines(data = tf_line,
color = ~palette_line(BanType),
weight = 2,
label = ~BanType,
group = "Winter Parking"
) %>%
addLegend(data = tf_line,
position = "bottomright",
pal = palette_line,
values = ~BanType,
title = "Ban Type",
opacity = 1) %>%
addCircleMarkers(
data = tf_water,
fillColor = ~palette_pts(SURVEYTYPE), # Color based on the 'category' column
fillOpacity = 0.8, # Adjust opacity
radius = 5, # Set marker size
stroke = TRUE, # Add stroke to the markers
weight = 1, # Set stroke weight
color = "#000000",
label = tf_water$SURVEYTYPE,
group = "Water Quality"
) %>%
addLegend(data = tf_water,
position = "bottomleft",
pal = palette_pts,
values = ~SURVEYTYPE,
title = "Survey Type",
opacity = 1) %>%
addPolygons(data = tf_pond, color = "blue", label = tf_pond$NAME, fillOpacity = 1,group = "Water Pond") %>%
addLayersControl(baseGroups = c("OpenTopo", "StamenToner"), overlayGroups = c("Water Pond", "Winter Parking","Water Quality"),
position = "topright")
library(htmlwidgets)
saveWidget(final_map, ".\\leaflet_map_R.html", selfcontained = TRUE)